// 导入所需的模块
import Database from 'better-sqlite3';
import path from 'path';
import fs from 'fs';

// 定义数据库文件路径
const DB_PATH = path.join(process.cwd(), 'data', 'delivery-management.db');

// 设备接口定义 - 用于存储设备的基本信息
export interface Device {
  id?: number;                    // 设备ID - 自增主键
  device_id: number;             // 设备编号 - 业务编号
  name: string;                  // 设备名称 - 设备的显示名称
  classification_name: string;    // 设备分类名称 - 设备所属分类
  classification_code: string;    // 设备分类代码 - 分类编码
  specialty: string;             // 专业 - 所属专业领域
  naming_table_id: string;       // 命名表ID - 关联命名规则表
  position_table_id: string;     // 位置表ID - 关联位置信息表
  base_params_table_id: string;  // 基本参数表ID - 关联基础参数表
  tech_spec_table_id: string;    // 技术规格表ID - 关联技术规格表
  sequence_number: string;       // 序号 - 排序编号
  remarks: string;               // 备注 - 其他补充说明
  created_at?: string;           // 创建时间 - 记录创建的时间戳
  updated_at?: string;           // 更新时间 - 最后修改的时间戳
}

// 命名参数接口定义 - 用于存储设备的命名相关参数
export interface NamingParameter {
  id?: number;                   // 参数ID - 自增主键
  device_id: number;            // 关联的设备ID - 外键关联设备表
  parameter_name: string;       // 参数名称 - 参数的显示名称
  parameter_value: string;      // 参数值 - 参数的实际值
  data_type?: string;          // 数据类型 - 参数值的数据类型
  is_required?: boolean;       // 是否必填 - 标识参数是否为必填项
  created_at?: string;         // 创建时间 - 记录创建的时间戳
  updated_at?: string;         // 更新时间 - 最后修改的时间戳
}

// 位置参数接口定义 - 用于存储设备的位置相关参数
export interface PositionParameter {
  id?: number;                  // 参数ID - 自增主键
  device_id: number;           // 关联的设备ID - 外键关联设备表
  parameter_name: string;      // 参数名称 - 参数的显示名称
  parameter_value: string;     // 参数值 - 参数的实际值
  data_type?: string;         // 数据类型 - 参数值的数据类型
  is_required?: boolean;      // 是否必填 - 标识参数是否为必填项
  created_at?: string;        // 创建时间 - 记录创建的时间戳
  updated_at?: string;        // 更新时间 - 最后修改的时间戳
}

// 基本参数接口定义 - 用于存储设备的基础技术参数
export interface BaseParameter {
  id?: number;                 // 参数ID - 自增主键
  device_id: number;          // 关联的设备ID - 外键关联设备表
  parameter_name: string;     // 参数名称 - 参数的显示名称
  parameter_value: string;    // 参数值 - 参数的实际值
  data_type?: string;        // 数据类型 - 参数值的数据类型
  measurement_unit?: string; // 计量单位 - 参数值的度量单位
  is_required?: boolean;     // 是否必填 - 标识参数是否为必填项
  created_at?: string;       // 创建时间 - 记录创建的时间戳
  updated_at?: string;       // 更新时间 - 最后修改的时间戳
}

// SQLite数据库类 - 提供数据库操作的核心功能
export class RealSqliteDatabase {
  private db: Database.Database; // SQLite数据库实例
  private dbPath: string; // 数据库文件路径

  // 构造函数 - 初始化数据库连接并确保数据库结构
  constructor(dbPath: string = DB_PATH) {
    this.dbPath = dbPath;
    this.ensureDataDirectory();
    this.db = new Database(this.dbPath);
    this.initializeDatabase();
  }

  // 确保数据目录存在 - 如果不存在则创建
  private ensureDataDirectory() {
    const dataDir = path.dirname(this.dbPath);
    if (!fs.existsSync(dataDir)) {
      fs.mkdirSync(dataDir, { recursive: true });
    }
  }

  // 初始化数据库 - 创建必要的表结构
  private initializeDatabase() {
    // 创建设备表
    this.db.exec(`
      CREATE TABLE IF NOT EXISTS devices (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        device_id INTEGER UNIQUE NOT NULL,
        name TEXT NOT NULL,
        classification_name TEXT NOT NULL,
        classification_code TEXT NOT NULL,
        specialty TEXT NOT NULL,
        naming_table_id TEXT,
        position_table_id TEXT,
        base_params_table_id TEXT,
        tech_spec_table_id TEXT,
        sequence_number TEXT,
        remarks TEXT,
        created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
        updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
      )
    `);

    // 创建命名参数表
    this.db.exec(`
      CREATE TABLE IF NOT EXISTS naming_parameters (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        device_id INTEGER NOT NULL,
        parameter_name TEXT NOT NULL,
        parameter_value TEXT,
        data_type TEXT,
        is_required BOOLEAN DEFAULT 0,
        created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
        updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
        FOREIGN KEY (device_id) REFERENCES devices (id) ON DELETE CASCADE
      )
    `);

    // 创建位置参数表
    this.db.exec(`
      CREATE TABLE IF NOT EXISTS position_parameters (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        device_id INTEGER NOT NULL,
        parameter_name TEXT NOT NULL,
        parameter_value TEXT,
        data_type TEXT,
        is_required BOOLEAN DEFAULT 0,
        created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
        updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
        FOREIGN KEY (device_id) REFERENCES devices (id) ON DELETE CASCADE
      )
    `);

    // 创建基本参数表
    this.db.exec(`
      CREATE TABLE IF NOT EXISTS base_parameters (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        device_id INTEGER NOT NULL,
        parameter_name TEXT NOT NULL,
        parameter_value TEXT,
        data_type TEXT,
        measurement_unit TEXT,
        is_required BOOLEAN DEFAULT 0,
        created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
        updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
        FOREIGN KEY (device_id) REFERENCES devices (id) ON DELETE CASCADE
      )
    `);

    // 创建索引以提高查询性能
    this.db.exec(`CREATE INDEX IF NOT EXISTS idx_devices_specialty ON devices (specialty)`);
    this.db.exec(`CREATE INDEX IF NOT EXISTS idx_devices_device_id ON devices (device_id)`);
    this.db.exec(`CREATE INDEX IF NOT EXISTS idx_naming_parameters_device_id ON naming_parameters (device_id)`);
    this.db.exec(`CREATE INDEX IF NOT EXISTS idx_position_parameters_device_id ON position_parameters (device_id)`);
    this.db.exec(`CREATE INDEX IF NOT EXISTS idx_base_parameters_device_id ON base_parameters (device_id)`);
  }

  // 插入设备记录 - 创建新的设备记录并返回完整的设备对象
  insertDevice(device: Partial<Device>): Device {
    // 获取当前最大的id
    const maxIdResult = this.db.prepare('SELECT MAX(id) as maxId FROM devices').get() as { maxId: number | null };
    const nextId = (maxIdResult?.maxId || 0) + 1;
    
    const sql = `
      INSERT INTO devices (
        id,
        name,
        classification_name,
        classification_code,
        specialty,
        naming_table_id,
        position_table_id,
        base_params_table_id,
        tech_spec_table_id,
        sequence_number,
        remarks
      ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    `;
    
    const result = this.db.prepare(sql).run(
      nextId,
      device.name,
      device.classification_name,
      device.classification_code,
      device.specialty,
      device.naming_table_id || null,
      device.position_table_id || null,
      device.base_params_table_id || null,
      device.tech_spec_table_id || null,
      device.sequence_number || null,
      device.remarks || null
    );

    return {
      id: result.lastInsertRowid as number,
      ...device
    } as Device;
  }

  // 获取所有设备 - 返回数据库中的所有设备记录
  getAllDevices(): Device[] {
    const stmt = this.db.prepare('SELECT * FROM devices ORDER BY id');
    return stmt.all() as Device[];
  }

  // 按专业获取设备 - 返回指定专业的所有设备
  getDevicesBySpecialty(specialty: string): Device[] {
    const stmt = this.db.prepare('SELECT * FROM devices WHERE specialty = ? ORDER BY id');
    return stmt.all(specialty) as Device[];
  }

  // 按ID获取设备 - 返回指定ID的设备记录
  getDeviceById(id: number): Device | null {
    const stmt = this.db.prepare('SELECT * FROM devices WHERE id = ?');
    return stmt.get(id) as Device || null;
  }

  // 按设备编号获取设备 - 返回指定设备编号的设备记录
  getDeviceByDeviceId(deviceId: number): Device | null {
    const stmt = this.db.prepare('SELECT * FROM devices WHERE device_id = ?');
    return stmt.get(deviceId) as Device || null;
  }

  // 插入命名参数 - 创建新的命名参数记录
  insertNamingParameter(param: Omit<NamingParameter, 'id' | 'created_at' | 'updated_at'>): NamingParameter {
    const now = new Date().toISOString();
    const stmt = this.db.prepare(`
      INSERT INTO naming_parameters (device_id, parameter_name, parameter_value, data_type, is_required, created_at, updated_at)
      VALUES (?, ?, ?, ?, ?, ?, ?)
    `);
    
    const result = stmt.run(
      param.device_id,
      param.parameter_name,
      param.parameter_value,
      param.data_type,
      param.is_required ? 1 : 0,
      now,
      now
    );

    return {
      ...param,
      id: result.lastInsertRowid as number,
      created_at: now,
      updated_at: now
    };
  }

  // 获取设备的命名参数 - 返回指定设备ID的所有命名参数
  getNamingParametersByDeviceId(deviceId: number): NamingParameter[] {
    const stmt = this.db.prepare('SELECT * FROM naming_parameters WHERE device_id = ? ORDER BY id');
    return stmt.all(deviceId) as NamingParameter[];
  }

  // 插入位置参数 - 创建新的位置参数记录
  insertPositionParameter(param: Omit<PositionParameter, 'id' | 'created_at' | 'updated_at'>): PositionParameter {
    const now = new Date().toISOString();
    const stmt = this.db.prepare(`
      INSERT INTO position_parameters (device_id, parameter_name, parameter_value, data_type, is_required, created_at, updated_at)
      VALUES (?, ?, ?, ?, ?, ?, ?)
    `);
    
    const result = stmt.run(
      param.device_id,
      param.parameter_name,
      param.parameter_value,
      param.data_type,
      param.is_required ? 1 : 0,
      now,
      now
    );

    return {
      ...param,
      id: result.lastInsertRowid as number,
      created_at: now,
      updated_at: now
    };
  }

  // 获取设备的位置参数 - 返回指定设备ID的所有位置参数
  getPositionParametersByDeviceId(deviceId: number): PositionParameter[] {
    const stmt = this.db.prepare('SELECT * FROM position_parameters WHERE device_id = ? ORDER BY id');
    return stmt.all(deviceId) as PositionParameter[];
  }

  // 获取设备特定表模板的位置参数 - 根据设备ID和表模板ID查询位置参数
  getPositionParametersByDeviceAndTemplate(deviceId: number, tableTemplateId: string): PositionParameter[] {
    const stmt = this.db.prepare('SELECT * FROM position_parameters WHERE device_id = ? AND table_template_id = ? ORDER BY id');
    return stmt.all(deviceId, tableTemplateId) as PositionParameter[];
  }

  // 插入基本参数 - 创建新的基本参数记录
  insertBaseParameter(param: Omit<BaseParameter, 'id' | 'created_at' | 'updated_at'>): BaseParameter {
    const now = new Date().toISOString();
    const stmt = this.db.prepare(`
      INSERT INTO base_parameters (device_id, parameter_name, parameter_value, data_type, measurement_unit, is_required, created_at, updated_at)
      VALUES (?, ?, ?, ?, ?, ?, ?, ?)
    `);
    
    const result = stmt.run(
      param.device_id,
      param.parameter_name,
      param.parameter_value,
      param.data_type,
      param.measurement_unit,
      param.is_required ? 1 : 0,
      now,
      now
    );

    return {
      ...param,
      id: result.lastInsertRowid as number,
      created_at: now,
      updated_at: now
    };
  }

  // 获取设备的基本参数 - 返回指定设备ID的所有基本参数
  getBaseParametersByDeviceId(deviceId: number): BaseParameter[] {
    const stmt = this.db.prepare('SELECT * FROM base_parameters WHERE device_id = ? ORDER BY id');
    return stmt.all(deviceId) as BaseParameter[];
  }

  // 获取仪表盘统计数据 - 按专业统计设备数量
  getDashboardStats() {
    const stmt = this.db.prepare('SELECT specialty, COUNT(*) as count FROM devices GROUP BY specialty ORDER BY count DESC');
    const results = stmt.all() as { specialty: string; count: number }[];
    
    return results.map(result => ({
      name: result.specialty,
      count: result.count,
      devices: this.getDevicesBySpecialty(result.specialty)
    }));
  }

  // 清空数据库 - 删除所有数据但保留表结构
  clearDatabase() {
    this.db.exec('DELETE FROM base_parameters');
    this.db.exec('DELETE FROM position_parameters');
    this.db.exec('DELETE FROM naming_parameters');
    this.db.exec('DELETE FROM devices');
  }

  // 获取设备及其所有参数 - 返回设备完整信息
  getDeviceWithParameters(deviceId: number) {
    const device = this.getDeviceById(deviceId);
    if (!device) return null;

    return {
      device,
      namingParameters: this.getNamingParametersByDeviceId(deviceId),
      positionParameters: this.getPositionParametersByDeviceId(deviceId),
      baseParameters: this.getBaseParametersByDeviceId(deviceId)
    };
  }

  // 根据设备编号获取命名参数 - API兼容性方法
  getNamingParameters(deviceId: number): NamingParameter[] {
    const device = this.getDeviceByDeviceId(deviceId);
    if (!device || !device.id) return [];
    return this.getNamingParametersByDeviceId(device.id);
  }

  // 根据设备编号获取位置参数 - API兼容性方法
  getPositionParameters(deviceId: number): PositionParameter[] {
    const device = this.getDeviceByDeviceId(deviceId);
    if (!device || !device.id) return [];
    return this.getPositionParametersByDeviceId(device.id);
  }

  // 根据设备编号获取基本参数 - API兼容性方法
  getBaseParameters(deviceId: number): BaseParameter[] {
    const device = this.getDeviceByDeviceId(deviceId);
    if (!device || !device.id) return [];
    return this.getBaseParametersByDeviceId(device.id);
  }

  // 删除设备的命名参数 - 清除指定设备的所有命名参数
  deleteNamingParameters(deviceId: number) {
    const device = this.getDeviceByDeviceId(deviceId);
    if (!device || !device.id) return;
    const stmt = this.db.prepare('DELETE FROM naming_parameters WHERE device_id = ?');
    stmt.run(device.id);
  }

  // 删除设备的位置参数 - 清除指定设备的所有位置参数
  deletePositionParameters(deviceId: number) {
    const device = this.getDeviceByDeviceId(deviceId);
    if (!device || !device.id) return;
    const stmt = this.db.prepare('DELETE FROM position_parameters WHERE device_id = ?');
    stmt.run(device.id);
  }

  // 删除设备的基本参数 - 清除指定设备的所有基本参数
  deleteBaseParameters(deviceId: number) {
    const device = this.getDeviceByDeviceId(deviceId);
    if (!device || !device.id) return;
    const stmt = this.db.prepare('DELETE FROM base_parameters WHERE device_id = ?');
    stmt.run(device.id);
  }

  // 更新命名参数值 - 修改指定参数的值
  updateNamingParameterValue(parameterId: number, value: string): NamingParameter | null {
    const now = new Date().toISOString();
    const stmt = this.db.prepare('UPDATE naming_parameters SET parameter_value = ?, updated_at = ? WHERE id = ?');
    const result = stmt.run(value, now, parameterId);
    
    if (result.changes > 0) {
      const getStmt = this.db.prepare('SELECT * FROM naming_parameters WHERE id = ?');
      return getStmt.get(parameterId) as NamingParameter;
    }
    return null;
  }

  // 更新位置参数值 - 修改指定参数的值
  updatePositionParameterValue(parameterId: number, value: string): PositionParameter | null {
    const now = new Date().toISOString();
    const stmt = this.db.prepare('UPDATE position_parameters SET parameter_value = ?, updated_at = ? WHERE id = ?');
    const result = stmt.run(value, now, parameterId);
    
    if (result.changes > 0) {
      const getStmt = this.db.prepare('SELECT * FROM position_parameters WHERE id = ?');
      return getStmt.get(parameterId) as PositionParameter;
    }
    return null;
  }

  // 更新基本参数值 - 修改指定参数的值
  updateBaseParameterValue(parameterId: number, value: string): BaseParameter | null {
    const now = new Date().toISOString();
    const stmt = this.db.prepare('UPDATE base_parameters SET parameter_value = ?, updated_at = ? WHERE id = ?');
    const result = stmt.run(value, now, parameterId);
    
    if (result.changes > 0) {
      const getStmt = this.db.prepare('SELECT * FROM base_parameters WHERE id = ?');
      return getStmt.get(parameterId) as BaseParameter;
    }
    return null;
  }

  // 批量保存参数
  batchSaveParameters(parameters: { id: number; value: string; type: 'naming' | 'position' | 'base' }[]) {
    const transaction = this.db.transaction(() => {
      const now = new Date().toISOString();
      
      for (const param of parameters) {
        if (param.type === 'naming') {
          const stmt = this.db.prepare('UPDATE naming_parameters SET parameter_value = ?, updated_at = ? WHERE id = ?');
          stmt.run(param.value, now, param.id);
        } else if (param.type === 'position') {
          const stmt = this.db.prepare('UPDATE position_parameters SET parameter_value = ?, updated_at = ? WHERE id = ?');
          stmt.run(param.value, now, param.id);
        } else if (param.type === 'base') {
          const stmt = this.db.prepare('UPDATE base_parameters SET parameter_value = ?, updated_at = ? WHERE id = ?');
          stmt.run(param.value, now, param.id);
        }
      }
    });
    
    transaction();
  }

  // 从JSON数据迁移到SQLite数据库
  migrateFromJsonData(jsonDevices: any[]) {
    const transaction = this.db.transaction(() => {
      console.log(`开始迁移 ${jsonDevices.length} 个设备到真正的SQLite数据库...`);
      
      for (const jsonDevice of jsonDevices) {
        try {
          // 插入设备
          const device = this.insertDevice({
            device_id: jsonDevice.device_id || jsonDevice.设备ID || 0,
            name: jsonDevice.name || jsonDevice['设备表及材料表中的实体对象名称'] || '',
            classification_name: jsonDevice.classification_name || jsonDevice['对应的对象分类标准中的中文名称'] || '',
            classification_code: jsonDevice.classification_code || jsonDevice['分类码'] || '',
            specialty: jsonDevice.specialty || '配管专业',
            naming_table_id: jsonDevice.naming_table_id || jsonDevice['对象命名'] || '',
            position_table_id: jsonDevice.position_table_id || jsonDevice['位置信息'] || '',
            base_params_table_id: jsonDevice.base_params_table_id || jsonDevice['基础参数'] || '',
            tech_spec_table_id: jsonDevice.tech_spec_table_id || jsonDevice['技术规格书'] || '',
            sequence_number: jsonDevice.sequence_number?.toString() || jsonDevice.序号?.toString() || '',
            remarks: jsonDevice.remarks || jsonDevice.备注 || ''
          });
          
          console.log(`迁移设备: ${device.name} (${device.device_id}) -> ID: ${device.id}`);
          
          // 为每个设备创建示例参数
          if (device.id) {
            this.createSampleParameters(device.id);
          }
        } catch (error) {
          console.error(`迁移设备失败:`, jsonDevice, error);
        }
      }
    });
    
    transaction();
    console.log('SQLite数据库迁移完成！');
  }

  // 创建示例参数
  private createSampleParameters(deviceId: number) {
    // 创建命名参数示例
    this.insertNamingParameter({
      device_id: deviceId,
      parameter_name: '设备位号',
      parameter_value: '',
      data_type: 'string',
      is_required: true
    });
    
    this.insertNamingParameter({
      device_id: deviceId,
      parameter_name: '设备名称',
      parameter_value: '',
      data_type: 'string',
      is_required: true
    });
    
    this.insertNamingParameter({
      device_id: deviceId,
      parameter_name: '设备规格',
      parameter_value: '',
      data_type: 'string',
      is_required: false
    });

    // 创建位置参数示例
    this.insertPositionParameter({
      device_id: deviceId,
      parameter_name: '所在区域',
      parameter_value: '',
      data_type: 'string',
      is_required: true
    });
    
    this.insertPositionParameter({
      device_id: deviceId,
      parameter_name: '安装位置',
      parameter_value: '',
      data_type: 'string',
      is_required: true
    });
    
    this.insertPositionParameter({
      device_id: deviceId,
      parameter_name: '坐标信息',
      parameter_value: '',
      data_type: 'string',
      is_required: false
    });

    // 创建基本参数示例
    this.insertBaseParameter({
      device_id: deviceId,
      parameter_name: '额定流量',
      parameter_value: '',
      data_type: 'number',
      measurement_unit: 'm³/h',
      is_required: true
    });
    
    this.insertBaseParameter({
      device_id: deviceId,
      parameter_name: '额定压力',
      parameter_value: '',
      data_type: 'number',
      measurement_unit: 'MPa',
      is_required: true
    });
    
    this.insertBaseParameter({
      device_id: deviceId,
      parameter_name: '额定功率',
      parameter_value: '',
      data_type: 'number',
      measurement_unit: 'kW',
      is_required: false
    });
  }

  // 关闭数据库连接
  close() {
    this.db.close();
  }
}

// 导出数据库实例 - 创建一个全局可用的数据库对象
export const realSqliteDb = new RealSqliteDatabase(); 

// 导出获取数据库实例的函数
export function getDb(): RealSqliteDatabase {
  return new RealSqliteDatabase();
} 